//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#ifndef _DISTANCEBINDINGSITE_H_
#define	_DISTANCEBINDINGSITE_H_
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "libraries.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

#include <iostream>

#include <zlib.h>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//

struct UniqueLigand {
    
  String* IDELigand;
  String* ResidueNumber;
  int     amountAtoms;

  UniqueLigand() {
    IDELigand     = new String();
    ResidueNumber = new String();
    amountAtoms   = 0;
  }

  UniqueLigand(struct UniqueLigand& uniqueLigand) {
    IDELigand     = new String(uniqueLigand.IDELigand);
    ResidueNumber = new String(uniqueLigand.ResidueNumber);
    amountAtoms   = uniqueLigand.amountAtoms;
  }

  UniqueLigand(struct UniqueLigand* uniqueLigand) {
    IDELigand     = new String(uniqueLigand->IDELigand);
    ResidueNumber = new String(uniqueLigand->ResidueNumber);
    amountAtoms   = uniqueLigand->amountAtoms;
  }

  ~UniqueLigand() {
    if (IDELigand)     delete this->IDELigand;
    if (ResidueNumber) delete this->ResidueNumber;
  }

};

typedef struct UniqueLigand UniqueLigand;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
class DistanceBindingSite {

  private:

    String*                idDB;
    String*                location;

    String*                outFile;
    
    String*                complementaryPDBInfo;
    String*                proteinSeq;

    TListE <String>*       ligandFormul;
    TListE <UniqueLigand>* listLigands;

    String*                chain;
    String*                identFasta;
    String*                listResidues;
    
    TListE <String>*       listATOM;
    TListE <String>*       listHETATM;

    double                 xLower;
    double                 xHigher;
    double                 yLower;
    double                 yHigher;
    double                 zLower;
    double                 zHigher;

    double                 distance;

  protected:

    bool   SplitColumn(char*, TListE <String>*, const char*);

    bool   GetListLigandInComplex();
    
    bool   GetLimitOfDistanceBindingSite(void);
    bool   GetLimitOfDistanceBindingSite(UniqueLigand*);

    bool   IsCoordinateInsideBox(double, double, double);
    bool   IsCoordinateInsideBox(double, double, double, double);

    char*  SubStrFromLine(char*, int, int, char*);

    char   OneLetterAACode(String*);

    double DistancePoints(double, double, double, double, double, double);

  public:

    DistanceBindingSite();
    DistanceBindingSite(const DistanceBindingSite&);
    DistanceBindingSite(const DistanceBindingSite*);

    ~DistanceBindingSite();

    void                   IDPDB(String*);
    void                   Location(String*);
    void                   OutFile(String*);
    void                   ComplementaryPDBInfo(String*);
    void                   ProteinSeq(String*);

    void                   LigandFormul(TListE <String>*);
    void                   ListLigands(TListE <UniqueLigand>*);
    
    void                   Chain(String*);
    void                   IdentFasta(String*);
    void                   ListResidues(String*);

    void                   ListATOM(TListE <String>*);
    void                   ListHETATM(TListE <String>*);

    void                   Distance(double);

    String*                IDPDB(void);
    String*                Location(void);
    String*                OutFile(void);
    String*                ComplementaryPDBInfo(void);
    String*                ProteinSeq(void);

    TListE <String>*       LigandFormul(void);
    TListE <UniqueLigand>* ListLigands(void);
    
    String*                Chain(void);
    String*                IdentFasta(void);
    String*                ListResidues(void);

    TListE <String>*       ListATOM(void);
    TListE <String>*       ListHETATM(void);

    double                 XLower(void);
    double                 XHigher(void);
    double                 YLower(void);
    double                 YHigher(void);
    double                 ZLower(void);
    double                 ZHigher(void);

    double                 Distance(void);

    UniqueLigand*          GetLargestLingand();

    bool                   ConstructPDBBindingSite(void);
    bool                   ConstructPDBBindingSite(UniqueLigand*);

};
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#endif
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
